package com.trigsoft.applist;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import android.app.Activity;
import android.database.Cursor;
import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.BaseExpandableListAdapter;
import android.widget.GridView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;

public class GridByAlphaAdapter extends BaseExpandableListAdapter
{
	private String[] alphabet;
	ArrayList<String> headers;
	Activity mCtx;
	private List<BaseAdapter> adapters;
	private final String[] columns = new String[] {DBHelper.KEY_ICON, DBHelper.KEY_LABEL};
	private final int[] to = new int[] {R.id.icon, R.id.name};
	private int[] keyMap;
	private TreeMap<String, BaseAdapter> adapterMap = new TreeMap<String, BaseAdapter>();
	private HashMap<String, Cursor> cursorMap = new HashMap<String, Cursor>(26);
	int numPerLine = 5;

	public GridByAlphaAdapter(Activity context, boolean recentTask, boolean isPortrait)
	{
		mCtx = context;

		if (!isPortrait)
			numPerLine = 7;

		ExecutorService exec;
		ArrayList<Future<String>> results;
		alphabet = mCtx.getResources().getStringArray(R.array.alphabet);
		int size = alphabet.length;

		if (recentTask)
		{
			size++;

			exec = Executors.newFixedThreadPool(size);
			results = new ArrayList<Future<String>>(size);
			adapters = new ArrayList<BaseAdapter>(size);
			headers = new ArrayList<String>(size);
			results.add(exec.submit(new GetTask()));
		} else
		{
			exec = Executors.newFixedThreadPool(size);
			results = new ArrayList<Future<String>>(size);
			adapters = new ArrayList<BaseAdapter>(size);
			headers = new ArrayList<String>(size);
		}

		for (String alpha : alphabet)
		{
			results.add(exec.submit(new GetCursor(alpha)));
		}

		for (Future<String> fs : results)
			try
			{
				String alpha = fs.get();
				if (alpha != null)
				{
					SimpleCursorAdapter sca = new SimpleCursorAdapter(mCtx, R.layout.item, cursorMap.get(alpha),
							columns, to);
					sca.setViewBinder(new ApplicationViewBinder());
					adapterMap.put(alpha, sca);
				}
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			} catch (ExecutionException e)
			{
				e.printStackTrace();
			} finally
			{
				exec.shutdown();
			}

		headers.addAll(adapterMap.keySet());
		adapters.addAll(adapterMap.values());

		keyMap = new int[size];
		int start = 0;
		if (recentTask)
		{
			keyMap[0] = 0;
			start = 1;
		}

		for (int i = start; i < alphabet.length; i++)
		{
			if (headers.contains(alphabet[i - start]))
				keyMap[i] = headers.indexOf(alphabet[i - start]);
			else
				keyMap[i] = keyMap[i - 1];

		}
		//alphaList[0] = mCtx.getString(R.string.recent_task);
	}

	public Object getChild(int groupPosition, int childPosition)
	{
		// TODO Auto-generated method stub
		/*if (mRecentTask && groupPosition == 0)
			return taskAdapter.getItem(childPosition);
		Cursor cursor = cursorList.get(groupPosition);
		cursor.moveToPosition(childPosition);*/
		return adapters.get(groupPosition).getItem(childPosition);
	}

	public long getChildId(int groupPosition, int childPosition)
	{
		// TODO Auto-generated method stub
		return childPosition;
	}

	public int getChildrenCount(int groupPosition)
	{
		// TODO Auto-generated method stub

		/*if (mRecentTask && groupPosition == 0 && taskAdapter.getCount() > 0)
			return 1;
		if (cursorList.get(groupPosition) != null)
			return 1;
		else
			return 0;*/
		if (groupPosition < headers.size())
			return 1;
		else
			return 0;

	}

	public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
			ViewGroup parent)
	{
		// TODO Auto-generated method stub
		int line;
		int count;

		GridView g = (GridView) convertView;
		BaseAdapter mAdapter = adapters.get(groupPosition);
		count = mAdapter.getCount();

		if (count % numPerLine == 0)
			line = count / numPerLine;
		else
			line = count / numPerLine + 1;
		AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, line * 120);
		if (g == null)
		{

			g = new GridView(mCtx);

			g.setGravity(Gravity.CENTER);
			g.setHorizontalSpacing(5);
			g.setVerticalSpacing(5);
			g.setNumColumns(numPerLine);
			g.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
			g.setVerticalScrollBarEnabled(false);
		}
		g.setLayoutParams(lp);

		g.setAdapter(mAdapter);
		g.setOnItemClickListener((OnItemClickListener) mCtx);
		g.setOnItemLongClickListener((OnItemLongClickListener) mCtx);

		return g;
	}

	public Object getGroup(int groupPosition)
	{
		// TODO Auto-generated method stub
		//return alphaList[groupPosition];
		return headers.get(groupPosition);
	}

	public int getGroupCount()
	{
		// TODO Auto-generated method stub
		//return alphaList.length;
		return headers.size();
	}

	public long getGroupId(int groupPosition)
	{
		// TODO Auto-generated method stub
		return groupPosition;
	}

	public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
	{
		// TODO Auto-generated method stub
		TextView tv = (TextView) convertView;
		if (tv == null)
		{
			AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
					ViewGroup.LayoutParams.WRAP_CONTENT);
			tv = new TextView(mCtx);
			tv.setLayoutParams(lp);
			tv.setGravity(Gravity.CENTER);
		}
		tv.setText(headers.get(groupPosition).toUpperCase());
		//tv.setText(alphabet.get(groupPosition).toUpperCase());
		tv.setTextColor(Color.WHITE);
		//tv.setBackgroundColor(Color.parseColor("#7f7f7f"));
		//tv.setOnTouchListener((OnTouchListener) mCtx);
		return tv;
	}

	public int getPosition(int pos)
	{
		return keyMap[pos];
	}

	public boolean hasStableIds()
	{
		// TODO Auto-generated method stub
		return false;
	}

	public boolean isChildSelectable(int groupPosition, int childPosition)
	{
		// TODO Auto-generated method stub
		return false;
	}

	private class GetTask implements Callable<String>
	{

		public String call() throws Exception
		{
			// TODO Auto-generated method stub
			adapters.add(new TaskAdapter(mCtx));
			headers.add(mCtx.getString(R.string.recent_task));
			return null;
		}

	}

	private class GetCursor implements Callable<String>
	{

		String alpha;

		public GetCursor(String alpha)
		{
			this.alpha = alpha;
		}

		public String call() throws Exception
		{
			// TODO Auto-generated method stub
			Cursor cursor = DBHelper.queryByAlpha(alpha);
			if (cursor.getCount() > 0)
			{
				cursorMap.put(alpha, cursor);
				return alpha;
			} else
			{
				return null;
			}
		}

	}

	public void setOrientation(boolean isPortrait)
	{
		// TODO Auto-generated method stub
		if (isPortrait)
			numPerLine = 5;
		else
			numPerLine = 7;
	}
}
